<?php
/**
 * Created by PhpStorm.
 * User: yangfan
 * Date: 2019/11/7
 * Time: 10:23 AM
 */

namespace App\BO\OrderStatus;

use App\BO\OrderStatus\State\AbnormalState;
use App\BO\OrderStatus\State\AOrderState;
use App\BO\OrderStatus\State\BeforeInitState;
use App\BO\OrderStatus\State\ClosedState;
use App\BO\OrderStatus\State\CommentedState;
use App\BO\OrderStatus\State\DistributingState;
use App\BO\OrderStatus\State\ExpireClosedState;
use App\BO\OrderStatus\State\NotPaidAndFinishedState;
use App\BO\OrderStatus\State\PendingCouldDispatchState;
use App\BO\OrderStatus\State\PendingState;
use App\BO\OrderStatus\State\Refund\RefundAdminRejectState;
use App\BO\OrderStatus\State\Refund\RefundCancelledByUserState;
use App\BO\OrderStatus\State\Refund\RefundFailedState;
use App\BO\OrderStatus\State\Refund\RefundingState;
use App\BO\OrderStatus\State\Refund\RefundSuccessState;
use App\BO\OrderStatus\State\Refund\RefundWaitingAdminCheckState;
use App\BO\OrderStatus\State\Refund\RefundWaitingThirdPartNotifyState;
use App\BO\OrderStatus\State\Report\ReportedState;
use App\BO\OrderStatus\State\Service\ServicingState;
use App\BO\OrderStatus\State\UserCanceledState;
use App\BO\OrderStatus\State\WaitingCommentState;
use App\BO\OrderStatus\State\WaitingServiceState;
use App\Entities\OrderEntity;
use App\Entities\OrderRefundModel;
use Illuminate\Support\Facades\Log;

/**
 * 订单状态
 * Class OrderStatus
 * @package App\BO\OrderStatus
 */
class OrderStatus implements IJudgeOrderState, IOperationJudgement
{
    use OrderJudgeStateTrait;

    /**
     * @var OrderEntity
     */
    private $order;

    /**
     * @var OrderStateContext
     */
    private $orderStateContext;

    /**
     * OrderStatus constructor.
     * @param OrderEntity $order
     */
    public function __construct(OrderEntity $order)
    {
        $this->order = $order;

        $this->orderStateContext = new OrderStateContext();
        $this->orderStateContext->setOrder($order);
        $this->orderStateContext->setOrderStateModifyStore(new OrderStateModifyStore($order));

        // 决定订单状态
        $currentState = $this->resolve();
        $this->orderStateContext->setOrderState($currentState);
    }

    /**
     * 决定当前定单状态
     * @return AOrderState
     */
    private function resolve()
    {
        $order = $this->order;
        $orderState = $order->getOrderState();
        $state = null;

        switch ($orderState) {
            case OrderStateDefinition::STATE_BEFORE_INIT:
                // 订单待初始化
                $state = OrderStateContext::getInstance(BeforeInitState::class);
                break;
            case OrderStateDefinition::STATE_WAITING_PAY:
                // 待支付状态
                $state = OrderStateContext::getInstance(PendingState::class);
                break;
            case OrderStateDefinition::STATE_WAITING_DISTRIBUTION:
                // 待分配
                $state = OrderStateContext::getInstance(DistributingState::class);
                break;
            case OrderStateDefinition::STATE_WAITING_SERVICE:
                // 待上门服务
                $state = OrderStateContext::getInstance(WaitingServiceState::class);
                break;
            case OrderStateDefinition::STATE_SERVICING:
                // 服务中
                $state = OrderStateContext::getInstance(ServicingState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_REJECT_BY_ADMIN:
                // 退款申请后台审核被拒绝
                $state = OrderStateContext::getInstance(RefundAdminRejectState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_WAITING_CHECK:
                // 退款申请后台审核
                $state = OrderStateContext::getInstance(RefundWaitingAdminCheckState::class);
                break;
            case OrderStateDefinition::STATE_USER_CANCEL:
                // 用户取消订单
                $state = OrderStateContext::getInstance(UserCanceledState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_WAITING_THIRD_PART_NOTIFY:
                // 退款等待第三方通知
                $state = OrderStateContext::getInstance(RefundWaitingThirdPartNotifyState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_CANCELLED_BY_USER:
                // 用户取消退款申请
                $state = OrderStateContext::getInstance(RefundCancelledByUserState::class);
                break;
            case OrderStateDefinition::STATE_REPORTED:
                // 已经报备
                $state = OrderStateContext::getInstance(ReportedState::class);
                break;
            case OrderStateDefinition::STATE_WAITING_PAY_COULD_DISPATCH:
                // 末支付可派单
                $state = OrderStateContext::getInstance(PendingCouldDispatchState::class);
                break;
            case OrderStateDefinition::STATE_NOT_PAID_NAD_FINISHED:
                // 末支付已经完成
                $state = OrderStateContext::getInstance(NotPaidAndFinishedState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_SUCCESS:
                // 退款成功
                $state = OrderStateContext::getInstance(RefundSuccessState::class);
                break;
            case OrderStateDefinition::STATE_REFUND_FAILED:
                // 退款失败
                $state = OrderStateContext::getInstance(RefundFailedState::class);
                break;
            case OrderStateDefinition::STATE_WAITING_COMMENT:
                // 待评价
                $state = OrderStateContext::getInstance(WaitingCommentState::class);
                break;
            case OrderStateDefinition::STATE_REVIEWED:
                // 已评价
                $state = OrderStateContext::getInstance(CommentedState::class);
                break;
            case OrderStateDefinition::STATE_EXPIRED:
                // 过期末支付，订单关闭
                $state = OrderStateContext::getInstance(ExpireClosedState::class);
                break;
        }

        if ($state) {
            return $state;
        }

        // 兼容老数据
        if ($this->isClosed()) { // 订单关闭
            $state = OrderStateContext::getInstance(ClosedState::class);
        } elseif ($this->isPending()) {  // 待支付状态
            $state = OrderStateContext::getInstance(PendingState::class);
        } elseif ($this->isDistributing()) {  // 待分配
            $state = OrderStateContext::getInstance(DistributingState::class);
        } elseif ($this->isWaitingService()) {  // 待上门服务
            $state = OrderStateContext::getInstance(WaitingServiceState::class);
        } elseif ($this->isRefunding()) {  // 等待退款
            $state = OrderStateContext::getInstance(RefundingState::class);
        } elseif ($this->isWaitingComment()) {// 待评价
            $state = OrderStateContext::getInstance(WaitingCommentState::class);
        } elseif ($this->reviewed()) {   // 已评价
            $state = OrderStateContext::getInstance(CommentedState::class);
        } elseif ($this->isExpireClosed()) {   // 过期末支付，订单关闭
            $state = OrderStateContext::getInstance(ExpireClosedState::class);
        }

        // 订单状态异常
        if (is_null($state)) {
            $state = OrderStateContext::getInstance(AbnormalState::class);
            Log::info('订单状态异常：' . $order);
        }

        return $state;
    }

    /**
     * @return AOrderState
     */
    private function getOrderState()
    {
        return $this->getOrderStateContext()->getOrderState();
    }

    /**
     * @return string
     */
    public function getStateDesc()
    {
        return $this->getOrderState()->getDesc();
    }

    /**
     * @return OrderStateContext
     */
    public function getOrderStateContext(): OrderStateContext
    {
        return $this->orderStateContext;
    }

    /**
     * 订单是否有支付信息
     * @return bool
     */
    public function hasPaidInfo()
    {
        return $this->order->getPaidAt() ? true : false;
    }

    /**
     * 订单是否有服务信息
     * @return bool
     */
    public function hasServiceInfo()
    {
        return $this->getOrderState()->hasServiceInfo();
    }

    /**
     * 当前状态是否能进行派单操作
     * @return bool
     */
    public function couldDistribute()
    {
        return $this->getOrderState()->couldDistribute();
    }

    /**
     * 当前状态是否能进行转派
     * @return bool
     */
    public function couldReDispatch()
    {
        return $this->getOrderState()->couldReDispatch();
    }

    /**
     * @inheritDoc
     */
    public function couldAdminApplyRefund()
    {
        return $this->getOrderState()->couldAdminApplyRefund();
    }

    /**
     * @inheritDoc
     */
    public function couldReport()
    {
        return $this->getOrderState()->couldReport();
    }

    /**
     * 订单是否有退款信息
     * @return bool
     */
    public function hasRefundInfo()
    {
        return $this->getOrderState()->hasRefundInfo();
    }

    /**
     * 订单是否有评价信息
     * @return bool
     */
    public function hasReviewInfo()
    {
        return $this->reviewed();
    }

    /**
     * 当前订单状态是否可以补单
     * @return bool
     */
    public function orderCouldSupplement()
    {
        if ($this->isDistributing() || $this->isWaitingService()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return bool
     */
    public function isNormalTrace()
    {
        return !$this->getOrder()->isAdminImport() &&
            (
                $this->isPending()
                || $this->isDistributing()
                || $this->isWaitingService()
                || $this->isWaitingComment()
                || $this->reviewed()
            );
    }

    /**
     * @return bool
     */
    public function isRefundTrace()
    {
        return !$this->getOrder()->isAdminImport() &&
            (OrderRefundModel::where('order_id', $this->getOrder()->getId())->count() == 1)  // 只能有一次退款审请
            && (
                $this->isRefundWaitingCheck()
                || $this->isRefundWaitingThirdPartNotify()
                || $this->isRefundSuccess()
            );
    }
}
